package com.winit.project.task;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.util.Constants;
import com.winit.common.util.FileUtil;
import com.winit.common.util.HttpClientUtil;
import com.winit.common.util.Md5Util;
import com.winit.project.core.bean.ProjectSqlInfo;
import com.winit.project.core.branch.Project;
import com.winit.project.util.ProjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * 抽取工程sql文件
 */

public class DrawSqlTask implements Callable {

    private static final Logger logger = LoggerFactory.getLogger(DrawSqlTask.class);

    private String dir;
    private String integrationId;
    private String proList;


    public DrawSqlTask(String dir, String integrationId, String proList) {
        this.dir = dir;
        this.integrationId = integrationId;
        this.proList = proList;
    }

    public String getIntegrationId() {
        return this.integrationId;
    }

    @Override
    public Object call() throws Exception {
        logger.info("抽取工程sql文件线程开启.dir=" + this.dir + ",proList=" + this.proList + ",integrationId=" + this.integrationId);

        try {
            JSONArray array = JSONArray.parseArray(this.proList);
            if (array.size() == 0) {
                this.taskClose();
            }
            List<JSONObject> list = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                List<JSONObject> l = new ArrayList<>();
                String name = array.getString(i);
                String trunkName = ProjectUtil.getTrunkProjectName(name);

                JSONObject jsonObject = new JSONObject();
                jsonObject.put("project", name);

                String bakDir = this.dir + "/" + trunkName + "_bak";

                logger.info("抽取工程sql文件开始.integrationId=" + this.integrationId + ",project=" + name);
                try {
                    File sqlfile = new File(this.dir + "/" + trunkName);
                    if (sqlfile.exists()) {
                        FileUtil.reNameFile(this.dir + "/" + trunkName, bakDir);
                    }
                    Project project = new Project(name, true);
                    project.drawProjectSql(this.dir, this.integrationId, l, true);
                    jsonObject.put("status", true);
                    jsonObject.put("sqls", l);
                } catch (Exception e) {
                    logger.error("抽取工程sql文件异常.integrationId=" + this.integrationId + ",project=" + name, e);
                    jsonObject.put("status", false);
                    jsonObject.put("desc", e.getLocalizedMessage());
                } finally {
                    if (jsonObject.getBoolean("status")) {
                        //比较新旧版本的区别
                        List<File> oldFile = new ArrayList<>();
                        FileUtil.getFileListF(new File(bakDir), oldFile);
                        List<File> newFile = new ArrayList<>();
                        FileUtil.getFileListF(new File(this.dir + "/" + trunkName), newFile);
                        StringBuffer buffer = new StringBuffer();
                        if (oldFile.size() == 0 && newFile.size() != 0) {
                            for (File n : newFile) {
                                buffer.append(n.getName()).append("#ADD#").append(getSqlInfo(n.getName(),l)).append("@");
                            }
                        } else if (oldFile.size() != 0 && newFile.size() == 0) {
                            for (File o : oldFile) {
                                buffer.append(o.getName()).append("#DEL@");
                            }
                        } else if (oldFile.size() == 0 && newFile.size() == 0) {
                        } else {
                            for (File n : newFile) {
                                File o = new File(n.getAbsolutePath().replace(this.dir + "/" + trunkName, bakDir));
                                if (!o.exists()) {
                                    buffer.append(n.getName()).append("#ADD#").append(getSqlInfo(n.getName(),l)).append("@");
                                    continue;
                                }
                                if (!Md5Util.getFileMd5(n.getAbsolutePath()).equals(Md5Util.getFileMd5(o.getAbsolutePath()))) {
                                    buffer.append(n.getName()).append("#UPDATE#").append(getSqlInfo(n.getName(),l)).append("@");
                                    continue;
                                }
                                buffer.append(n.getName()).append("#NO#").append(getSqlInfo(n.getName(),l)).append("@");
                            }
                            for (File o : oldFile) {
                                File n = new File(o.getAbsolutePath().replace(bakDir, this.dir + "/" + trunkName));
                                if (!n.exists()) {
                                    buffer.append(o.getName()).append("#DEL@");
                                    continue;
                                }
                            }
                        }
                        if (StringUtils.isEmpty(buffer.toString())) {
                            jsonObject.put("change_desc", "");
                        } else {
                            jsonObject.put("change_desc", buffer.toString().substring(0, buffer.toString().length() - 1));
                        }
                    } else {
                        jsonObject.put("change_desc", "抽取sql文件异常." + jsonObject.getString("desc"));
                    }
                    logger.info("com.winit.project.task.DrawSqlTask.call 删除备份目录 " + bakDir);
                    FileUtil.deleteFile(bakDir);
                }
                logger.info("抽取工程sql文件结束.integrationId=" + this.integrationId + ",project=" + name);
                list.add(jsonObject);
            }
            if (list.size() > 0) {
                JSONObject json = new JSONObject();
                json.put("list", list.toString());
                json.put("integration_id", this.integrationId);
                JSONObject jsonObject = HttpClientUtil.doPostForJson(Constants.BEETLE_PLAN_URL + "/integration/saveProjectSqlInfo", json.toString());
                logger.info("com.winit.project.task.DrawSqlTask.call 保存信息.integrationId=" + this.integrationId + ",rtn=" + jsonObject);
            }
        } catch (Exception e) {
            logger.error("抽取工程sql文件线程异常.dir=" + this.dir + ",proList=" + this.proList + ",integrationId=" + this.integrationId, e);
        } finally {
            this.taskClose();
            return null;
        }
    }

    private String getSqlInfo(String fileName,List<JSONObject> list){
        JSONObject jsonObject = new JSONObject();
        for (JSONObject object:list){
            if(fileName.equals(object.getString("file_name"))){
                jsonObject = object;
                break;
            }
        }
        return jsonObject.toJSONString();
    }

    private void taskClose() {
        logger.info("抽取工程sql文件线程关闭.dir=" + this.dir + ",proList=" + this.proList + ",integrationId=" + this.integrationId);
        DrawSqlTaskContainer.getInstance().removeTask(this.integrationId);
    }

}
